package com.junjiao.util.java.servlet;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
/**
 * 网络图片压缩处理
 * 			<p>chrom浏览器对请求有端口限制，需80-90端口间，经测试8999端口可用[错误 312 (net::ERR_UNSAFE_PORT)：未知错误。]</p>
 * @author jiaojun [junjiao.j@gmail.com]
 * @project：2car interface
 * @version:v1.1
 * @date:2012-11-28
 */
public class ImageZipServlet extends HttpServlet {

    private static final Log log = LogFactory.getLog(ImageZipServlet.class);
    private static int height = 0;
    private static int width = 0;
    
    static{
        System.setProperty("java.awt.headless", "true");
    }

    /**
     * /z_img/([0-9]+)/([0-9]+)/([a-z]+)
     * /zip/image/imageServlet?picUrl=$3&amp;width=$1&amp;height=$2
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
	    throws ServletException, IOException {
	response.setContentType("image/jpeg");
	response.setCharacterEncoding("UTF-8");

	String picUrl = request.getParameter("picUrl");
	String width = request.getParameter("width");
	String height = request.getParameter("height");

	BufferedImage image = null;
	if (null != picUrl && !"".equals(picUrl)) {
	    log.info("w.51auto.com zip image,picUrl:" + picUrl + "  width:" + width + "  height:" + height);
	    picUrl = new String(Base64.decodeBase64(picUrl.getBytes()));
	    log.info("picUrl:" + picUrl);

	    try {
		image = zoomImage(picUrl, Integer.parseInt(width),
			Integer.parseInt(height));
	    } catch (Exception e) {
		log.error(e.getMessage());
	    }
	} else {
	    image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
	}
//	ImageIO.write(image, "JPEG", response.getOutputStream());
	
	JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(response.getOutputStream());
	encoder.encode(image);
    }

    /**
     * 按指定大小缩放图片(java原生包，质量惨不忍睹)
     * 
     * @param inPutFile
     * @param outPutFile
     * @param height
     * @param width
     * @throws Exception
     */
    public static BufferedImage zoomImage(String picUrl, int width, int height)
	    throws Exception {
	BufferedImage source = loadImageUrl(picUrl);
	if (source == null) {
	    return null;
	}
	if (source.getWidth() / source.getHeight() >= width / height) {
	    if (source.getWidth() > width) {
		height = (source.getHeight() * width) / source.getWidth();
	    } else {
		width = source.getWidth();
		height = source.getHeight();
	    }
	} else {
	    if (source.getHeight() > height) {
		width = (source.getWidth() * height) / source.getHeight();
	    } else {
		width = source.getWidth();
		height = source.getHeight();
	    }
	}
	double hx = (double) height / source.getHeight();
	double wy = (double) width / source.getWidth();
	if (hx <= wy) {
	    wy = hx;
	    width = (int) (source.getWidth() * wy);
	} else {
	    hx = wy;
	    height = (int) (source.getHeight() * hx);
	}

	int type = source.getType();
	BufferedImage target = null;
	if (type == BufferedImage.TYPE_CUSTOM) { 
	    ColorModel cm = source.getColorModel();
	    WritableRaster raster = cm.createCompatibleWritableRaster(width,
		    height);
	    boolean alphaPremultiplied = cm.isAlphaPremultiplied();
	    target = new BufferedImage(cm, raster, alphaPremultiplied, null);
	} else {
	    target = new BufferedImage(width, height, type);
	}
	Graphics2D g = target.createGraphics();

	g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
		RenderingHints.VALUE_INTERPOLATION_BICUBIC);

	g.drawRenderedImage(source, AffineTransform.getScaleInstance(wy, hx));
	g.dispose();

	return target;
    }
    
    /**
     * 按指定大小缩放图片(java原生包，质量惨不忍睹)
     * 
     * @param inPutFile
     * @param outPutFile
     * @param height
     * @param width
     * @throws Exception
     */
    public static BufferedImage zoomImage(File inPutFile, int width, int height)
	    throws Exception {
	BufferedImage source = ImageIO.read(inPutFile);
	if (source == null) {
	    return null;
	}
	if (source.getWidth() / source.getHeight() >= width / height) {
	    if (source.getWidth() > width) {
		height = (source.getHeight() * width) / source.getWidth();
	    } else {
		width = source.getWidth();
		height = source.getHeight();
	    }
	} else {
	    if (source.getHeight() > height) {
		width = (source.getWidth() * height) / source.getHeight();
	    } else {
		width = source.getWidth();
		height = source.getHeight();
	    }
	}
	double hx = (double) height / source.getHeight();
	double wy = (double) width / source.getWidth();
	if (hx <= wy) {
	    wy = hx;
	    width = (int) (source.getWidth() * wy);
	} else {
	    hx = wy;
	    height = (int) (source.getHeight() * hx);
	}

	int type = source.getType();
	BufferedImage target = null;
	if (type == BufferedImage.TYPE_CUSTOM) { // handmade
	    ColorModel cm = source.getColorModel();
	    WritableRaster raster = cm.createCompatibleWritableRaster(width,
		    height);
	    boolean alphaPremultiplied = cm.isAlphaPremultiplied();
	    target = new BufferedImage(cm, raster, alphaPremultiplied, null);
	} else {
	    target = new BufferedImage(width, height, type);
	}
	Graphics2D g = target.createGraphics();

	g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
		RenderingHints.VALUE_INTERPOLATION_BICUBIC);

	g.drawRenderedImage(source, AffineTransform.getScaleInstance(wy, hx));
	g.dispose();

	return target;
    }

    /**
     * 读取指定图片的url地址，并转换为文件返回
     * 
     * @param imgUrl
     * @return
     */
    public static File readImg(String imgUrl) {
	BufferedImage img = loadImageUrl(imgUrl);
	String[] temp = imgUrl.split("/");
	String t = temp[temp.length - 1];
	writeImageLocal(t, img);

	return new File(t);
    }

    /**
     * 导入网络图片到缓冲区
     */
    public static BufferedImage loadImageUrl(String imgName) {
	try {
	    URL url = new URL(imgName);
	    return ImageIO.read(url);
	} catch (IOException e) {
	    log.error("导入网络图片到缓冲区，请检查网路正确性与图片正确性！");
	    log.error(e.getMessage());
	    e.printStackTrace();
	}
	return null;
    }

    /**
     * 生成新图片到本地
     */
    public static void writeImageLocal(String newImage, BufferedImage img) {
	if (newImage != null && img != null) {
	    try {
		File outputfile = new File(newImage);
		ImageIO.write(img, "jpg", outputfile);
	    } catch (IOException e) {
		log.error(e.getMessage());
		e.printStackTrace();
	    }
	}
    }
}
